package com.tich.user.service.impl;


import cn.hutool.core.lang.UUID;
import com.tich.constant.JwtConstant;
import com.tich.constant.RabbitMqConstant;
import com.tich.constant.RedisConstant;

import com.tich.context.UserContext;
import com.tich.exception.LoginErrorException;
import com.tich.exception.RegisterErrorException;

import com.tich.properties.JwtProperties;
import com.tich.user.domain.dto.UserLoginDTO;
import com.tich.user.domain.dto.UserRegisterDTO;
import com.tich.user.domain.entity.User;
import com.tich.user.domain.entity.UserInfo;
import com.tich.user.domain.vo.UserLoginVO;
import com.tich.user.domain.vo.UserProfileVO;
import com.tich.user.mapper.UserInfoMapper;
import com.tich.user.mapper.UserMapper;
import com.tich.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tich.utils.IdGeneratorUtil;
import com.tich.user.utils.PhoneNumberValidator;
import com.tich.utils.JwtUtil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateConfigurer;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 王志宇
 * @since 2025-05-06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 注册
     * @param userRegisterDTO
     */
    @Override
    @Transactional
    public void register(UserRegisterDTO userRegisterDTO) {
        //判断验证码
        String key = RedisConstant.CAPTCHA_HEAD + userRegisterDTO.getKey();
        String code = userRegisterDTO.getCaptcha();

        try {
            // 设置超时的 Redis 操作
            String rel_code =  stringRedisTemplate.opsForValue().getAndDelete(key);
            if (code == null || !code.equals(rel_code)) {
                throw new RegisterErrorException("验证码错误!");
            }
        } catch (RedisConnectionFailureException e) {
            throw new RegisterErrorException("验证码服务暂时不可用，请稍后重试");
        } catch (Exception e) {
            log.error("获取验证码失败", e);
            throw new RegisterErrorException("系统错误，请联系管理员");
        }

        //判断手机号是否合格
        String phone = userRegisterDTO.getPhone();
        if(phone == null || phone.isEmpty() || !PhoneNumberValidator.isValidPhoneNumber(phone)){
            throw  new RegisterErrorException("手机号格式错误!");
        }

        //判断密码是否为空
        if(StringUtils.isEmpty(userRegisterDTO.getPassword())){
            throw new RegisterErrorException("密码不能为空");
        }

        //查询是否有该用户
        User exituser = query().eq("phone", phone).one();
        if(exituser != null){
            throw new RegisterErrorException("用户已经存在!");
        }

        //注册用户
        String password = DigestUtils.md5DigestAsHex(userRegisterDTO.getPassword().getBytes());

        Long userId = IdGeneratorUtil.getInstance().nextId();

        User newuser = User.builder()
                .username(UUID.randomUUID().toString())
                .password(password)
                .id(userId)
                .phone(phone)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        this.save(newuser);
    }

    /**
     * 登录
     * @param userLoginDTO
     * @return
     */
    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        //查询是否有该用户
        User user = query().eq("phone", userLoginDTO.getPhone()).one();
        if(user == null){
            throw new LoginErrorException("账号不存在，请先注册!");
        }

        //判断密码是否正确
        String password = DigestUtils.md5DigestAsHex(userLoginDTO.getPassword().getBytes());
        if(!password.equals(user.getPassword())){
            throw new LoginErrorException("密码错误!");
        }

        //登录成功，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtConstant.USERID, user.getId());

        String token = JwtUtil.createJWT(jwtProperties.getSecretKey(),claims);

        //存入redis
        stringRedisTemplate.opsForValue().set(RedisConstant.TOKEN_HEADER + user.getId(), token, RedisConstant.TOKEN_TTL, TimeUnit.MINUTES);

        return UserLoginVO.builder()
                .id(user.getId())
                .token(token)
                .build();
    }

    /**
     * 获取用户基础信息
     * @return
     */
    @Override
    public UserProfileVO queryUserById() {
        Long userId = UserContext.getCurrentId();
        //TODO　1.查询Redis


        //2.查询数据库
        //获取用户信息
        User user = query().eq("id",userId ).one();
        if(user == null){
            return  UserProfileVO.builder().build();
        }
        //获取用户详细信息
        UserInfo userInfo = userInfoMapper.selectById(userId);
        if (userInfo == null) {
            return  UserProfileVO.builder()
                    .username(user.getUsername())
                    .image(user.getImage())
                    .build();
        }

        //　TODO 3.存入redis

        return UserProfileVO.builder()
                .username(user.getUsername())
                .image(user.getImage())
                .followee(userInfo.getFollowee())
                .fans(userInfo.getFans())
                .build();
    }

    @Override
    public void deleteById(Long id) {
        User user = query().eq("id", id).one();
       // this.removeById(UserContext.getCurrentId());
        rabbitTemplate.convertAndSend(RabbitMqConstant.USER_DIRECT,
                RabbitMqConstant.USER_DELETE_KEY,
                user);
    }
}
